package com.swedne.test.kt.flowExample

import android.database.CharArrayBuffer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.currentCoroutineContext
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.flow.zip
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import java.io.FileReader

class Test {
}

fun main() = runBlocking {
    println("runBlocking  ${currentCoroutineContext()}")
//    // 创建3个Flow,生产数据
//    var firstFlow = flowOf(1, 2)
//    val secondFlow = flow {
//        emit(3)
//        emit(4)
//    }
//    val thirdFlow = listOf(5, 6).asFlow()
//    firstFlow.collect {
//        println(it)
//    }
//    secondFlow.collect {
//        println(it)
//    }
//    thirdFlow.collect {
//        println(it)
//    }
    //转换操作符
    //1. map：对每个元素应用一个函数，并返回一个新的 Flow。（和集合的map一样）
    //2. filter：过滤出符合条件的元素。（和集合的filter一样）
    //3. transform：对每个元素应用一个自定义的转换，可以发射多个值（这是它和map的区别）
    //   flowOf(1, 2, 3).transform { value ->
    //    emit(value * 2)
    //    emit(value * 3)
    //}
    //4.take：只取前 n 个元素。（和集合的take一样）
//    flowOf(1, 2, 3).transform { value ->
//        emit(value * 2)
//        emit(value * 3)
//    }.collect {
//        println(it)
//    }
    //输出2 3 4 6 6 9
    //组合操作符
    //1.zip 合并
    /*    flowOf(1, 2).zip(flowOf("A", "B", "C")) { a, b -> "$a -> $b" }.collect {
            println(it)
        }

        val flow1 = flow {
            emit(1)
            delay(100)
            emit(2)
            delay(100)
            emit(3)
        }

        val flow2 = flow {
            emit("A")
            delay(500)
            emit("B")
            emit("C")
        }
        //1.zip 组合
        //合并两个Flow 的最新值。组合最新的值是什么意思呢？两个Flow中任意一个Flow有新的数据来了，那么就需要与另外一个Flow的最新的值进行组合。
        //比如flow2的最新值是A，那么flow1一旦emit发射一个新值1，那么A就会和1结合，flow1再emit发射一个新值2，还是和flow2的最新值A进行结合，这样组合出来的个数就不一定是某个flow数据流的个数。
        val combinedFlow = flow1.combine(flow2) { a, b -> "$a$b" }
        // 输出
        // 1A
        // 2A
        // 3A
        // 3B
        // 3C
        combinedFlow.collect { println(it) }

        //末端操作符
        flowOf(1, 2, 3).collect { println(it) }
        val list = flowOf(1, 2, 3).toList()
        val first = flowOf(1, 2, 3).first()*/

    //上下文操作符
    //flowOn 它会影响flow{}构建器函数和之前的中间操作符的执行上下文
    /*
        withContext(Dispatchers.Default){

        flow {
            for (i in 1..3) {
                println("flow  ${currentCoroutineContext()}")
                emit(i)
            }//上面的输出在Default上下文中
        }.flowOn(Dispatchers.Default)
            .map {
                println("map  ${currentCoroutineContext()}")
                it.toString()
            }
            //上面的输出在IO上下文中
            .flowOn(Dispatchers.IO)
            .collect {
                withContext(Dispatchers.IO) {
                    println("collect withContext ${currentCoroutineContext()}")
                }
                //不受flowOn上下文影响
                println("collect ${currentCoroutineContext()}")
                println(it)
            }

        }
    */

    //buffer：在不同上下文之间缓冲元素。
    //背压:当下游消费者无法以生产者生产或释放信息的速度进行消化时，就会发生背压
    //先看一下有缓冲区的情况
    /*    flowOf("A", "B", "C", "D", "E")
            .onEach { println("Woman matchmaker emits: $it") }
            .buffer()
            .run {
                collect {
                    //不会改变collect操作符本身的执行顺序
                    withContext(Dispatchers.IO) {
                        println("Girl appointment with: $it")
                        delay(1000)
                    }

                }
            }*/
    //有buffer输出A B C D E /A B C D E
    /*    flowOf("A","B","C","D","E")
            .onEach { println("Woman matchmaker emits: $it") }
            .collect {
                delay(1000)
                println("Girl appointment with: $it")
            }*/
    //没buffer输出A A B B C C D D E E

    /*    flowOf("A","B","C","D","E")
            .conflate()
            .onEach { println("Woman matchmaker emits: $it") }
            .collect {
                println("Girl appointment with: $it")
            }*/
    //conflate 只处理最新的值
    //输出Girl appointment with: A E


    var flow = flowOf("A", "B", "C", "D", "E")
        // 将此放在conflate()之后以观察实际接收的元素
        .stateIn(this, SharingStarted.WhileSubscribed(5000L), null)
        .onEach { println("Received by downstream: $it") }
    flow.collect {
        println("Girl appointment with2: $it")
    }
    flow.collect {
        println("Girl appointment with1: $it")
    }

    launch {
       val fileReader = FileReader("")
        var temp=CharArray(8*1024)
        while (fileReader.read(temp)>0){

        }
    }
}